/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 * Description: 获取动态库中runtime接口函数的适配接口私有头文件.
 * Author: qingjicheng
 * Create: 2023/1/4
 */

#ifndef DLRTS_FUNCTION_H
#define DLRTS_FUNCTION_H

#include <mutex>
#include "hccl_dl.h"
#include "log.h"

template<const char *soName>
class DlRtsFunction {
public:
    explicit DlRtsFunction() = default;
    virtual ~DlRtsFunction()
    {
        if (handle_ != nullptr) {
            HcclDlclose(handle_);
            handle_ = nullptr;
        }
    }

    template<const char *funcName> void *Handle()
    {
        Init();
        if (handle_ == nullptr) {
            return nullptr;
        }
        return HcclDlsym(handle_, funcName);
    }
private:
    void Init()
    {
        std::lock_guard<std::mutex> lock(handleMutex_);
        if (isInit_) {
            return;
        }
        HCCL_INFO("open so: %s", soName);
        handle_ = HcclDlopen(soName, RTLD_NOW);
        const char* errMsg = dlerror();
        CHK_PRT_RET(handle_ == nullptr, HCCL_ERROR("dlopen [%s] failed, %s", soName,\
            (errMsg == nullptr) ? "please check the file exist or permission denied." : errMsg),);
        isInit_ = true;
    }
    void *handle_ = nullptr;
    std::mutex handleMutex_;
    bool isInit_ = false;
};
#endif
